"""
异步处理模块
"""

import threading
import queue
from typing import Callable, Any, Optional
from dataclasses import dataclass
from concurrent.futures import ThreadPoolExecutor, Future
import time


@dataclass
class Task:
    """任务数据类"""
    func: Callable
    args: tuple = ()
    kwargs: dict = None
    callback: Optional[Callable] = None
    error_callback: Optional[Callable] = None
    progress_callback: Optional[Callable] = None
    task_id: str = None
    
    def __post_init__(self):
        if self.kwargs is None:
            self.kwargs = {}
        if self.task_id is None:
            self.task_id = f"task_{int(time.time() * 1000)}"


class AsyncProcessor:
    """异步处理器"""
    
    def __init__(self, max_workers: int = 3):
        self.max_workers = max_workers
        self.executor = ThreadPoolExecutor(max_workers=max_workers)
        self.active_tasks = {}
        self.task_counter = 0
        self._shutdown = False
    
    def submit_task(self, task: Task) -> str:
        """提交任务"""
        if self._shutdown:
            raise RuntimeError("AsyncProcessor已关闭")
        
        future = self.executor.submit(self._execute_task, task)
        self.active_tasks[task.task_id] = {
            'task': task,
            'future': future,
            'start_time': time.time()
        }
        
        return task.task_id
    
    def _execute_task(self, task: Task):
        """执行任务"""
        try:
            # 执行任务
            result = task.func(*task.args, **task.kwargs)
            
            # 调用成功回调
            if task.callback:
                try:
                    task.callback(result)
                except Exception as e:
                    print(f"回调函数执行失败: {e}")
            
            return result
            
        except Exception as e:
            # 调用错误回调
            if task.error_callback:
                try:
                    task.error_callback(e)
                except Exception as callback_error:
                    print(f"错误回调函数执行失败: {callback_error}")
            else:
                print(f"任务执行失败: {e}")
            
            raise e
        finally:
            # 清理任务记录
            if task.task_id in self.active_tasks:
                del self.active_tasks[task.task_id]
    
    def cancel_task(self, task_id: str) -> bool:
        """取消任务"""
        if task_id in self.active_tasks:
            future = self.active_tasks[task_id]['future']
            success = future.cancel()
            if success:
                del self.active_tasks[task_id]
            return success
        return False
    
    def get_task_status(self, task_id: str) -> Optional[dict]:
        """获取任务状态"""
        if task_id in self.active_tasks:
            task_info = self.active_tasks[task_id]
            future = task_info['future']
            
            return {
                'task_id': task_id,
                'running': future.running(),
                'done': future.done(),
                'cancelled': future.cancelled(),
                'start_time': task_info['start_time'],
                'duration': time.time() - task_info['start_time']
            }
        return None
    
    def get_active_tasks(self) -> list:
        """获取所有活跃任务"""
        return list(self.active_tasks.keys())
    
    def shutdown(self, wait: bool = True):
        """关闭处理器"""
        self._shutdown = True
        self.executor.shutdown(wait=wait)
        self.active_tasks.clear()


class ProgressTracker:
    """进度跟踪器"""
    
    def __init__(self, total: int = 100):
        self.total = total
        self.current = 0
        self.callbacks = []
        self._lock = threading.Lock()
    
    def add_callback(self, callback: Callable[[int, int], None]):
        """添加进度回调"""
        self.callbacks.append(callback)
    
    def update(self, value: int):
        """更新进度"""
        with self._lock:
            self.current = min(value, self.total)
            self._notify_callbacks()
    
    def increment(self, step: int = 1):
        """增加进度"""
        with self._lock:
            self.current = min(self.current + step, self.total)
            self._notify_callbacks()
    
    def _notify_callbacks(self):
        """通知所有回调"""
        for callback in self.callbacks:
            try:
                callback(self.current, self.total)
            except Exception as e:
                print(f"进度回调执行失败: {e}")
    
    def reset(self, total: int = None):
        """重置进度"""
        with self._lock:
            if total is not None:
                self.total = total
            self.current = 0
            self._notify_callbacks()
    
    @property
    def percentage(self) -> float:
        """获取百分比"""
        if self.total == 0:
            return 0.0
        return (self.current / self.total) * 100
